/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = module.h                                           */
/*  NOTE      = 模块信息                                           */
/*  DATE      = 2014/09/29                                         */
/*******************************************************************/

#ifndef __MODULE_H_
#define __MODULE_H_

#include "frmem.h"
#include "frstr.h"
#include "frlist.h"
#include "frhash2.h"

#include "module_comm.h"
#include "conntrack.h"

/* L7层协议代号 */
#define APM_L7_UNKNOWN          0     /* 不明 */
#define APM_L7_DISABLE          1     /* 禁止 */
//#define APM_L7_ORACLE           10    /* oracle */
//#define APM_L7_MSSQL            11    /* mssql */
//#define APM_L7_HTTP             20    /* http */
//#define APM_L7_XML              21    /* xml */


/* L7层协议判断 */
#define APM_L7_IS_NO          0   /* 不是该协议 */
#define APM_L7_IS_YES         1   /* 是该协议 */
#define APM_L7_IS_UNKNOWN     2   /* 不能判断该协议 */
#define APM_L7_IS_DISABLE     3   /* 该协议禁止使用 */

#define APM_L7_ANALYZE_FAIL                 0x10           /* 0001 0000 解码失败 */
#define APM_L7_ANALYZE_REDETECT             0x20           /* 0010 0000 l7 协议重新判断 */
#define APM_L7_ANALYZE_TODO                 0x30           /* 0011 0000 解码还需要后续数据 */
#define APM_L7_ANALYZE_SUCC                 0x40           /* 0100 0000 解码成功 */
#define APM_L7_ANALYZE_STOP                 0x50           /* 0101 0000 解码结束 */

#define APM_L7_BIT_REQ                      0x01           /* request */
#define APM_L7_BIT_RESP                     0x02           /* response*/
#define APM_L7_BIT_LOGIN                    0x04           /* login */
#define APM_L7_BIT_LOGOUT                   0x08           /* logout */

#define APM_L7_ANALYZE_SET_REQ(x)           ( (x)|APM_L7_BIT_REQ )
#define APM_L7_ANALYZE_SET_RESP(x)          ( (x)|APM_L7_BIT_RESP )
#define APM_L7_ANALYZE_SET_LOGIN(x)         ( (x)|APM_L7_BIT_LOGIN )
#define APM_L7_ANALYZE_SET_LOGOUT(x)        ( (x)|APM_L7_BIT_LOGOUT )

#define APM_L7_ANALYZE_IS_REQ(x)            ( (x)&APM_L7_BIT_REQ )
#define APM_L7_ANALYZE_IS_RESP(x)           ( (x)&APM_L7_BIT_RESP )
#define APM_L7_ANALYZE_IS_LOGIN(x)          ( (x)&APM_L7_BIT_LOGIN )
#define APM_L7_ANALYZE_IS_LOGOUT(x)         ( (x)&APM_L7_BIT_LOGOUT )
#define APM_L7_ANALYZE_IS_SUCC(x)           ( ((x)&0xF0) == APM_L7_ANALYZE_SUCC )


typedef struct __st_trans_info {
    L4_transaction st_l4_trans;
    L7_transaction st_l7_trans;
} Frtrans_info;

//login状态
typedef enum __em_login_status {
    FRLOGIN_START = 1,
    FRLOGIN_SUCC,
    FRLOGIN_FAIL,
    FRLOGOUT_START,
    FRLOGOUT_END
} Frlogin_status;
#define FRLOGIN_STATUS_STR(x)           \
    (x==FRLOGIN_START?"login start":    \
            (x==FRLOGIN_SUCC?"login succ":      \
                (x==FRLOGIN_FAIL?"login fail":  \
                    (x==FRLOGOUT_START?"logout start":"logout"))))
/*
* L7_module是由C编写的最基本的L7分析模块，采用so方式动态加载
* 系统启动后每个模块应构造L7_module信息，调用register实现自注册
*/
struct __st_l7_module {
    int i_l7_proto;             /* 全局使用的l7代号，唯一，应申请后使用 */
    u_short us_l4_proto;        /* 1 协议没有指定或识别时,指定tcp/udp有效; 6(IPPROTO_TCP)/17(IPPROTO_UDP)
                                   2 强行指定时没有该限制 */
    char *p_module_name;        /* 模块名称 */
    char *p_version;            /* 版本号 */

    /* 构造函数
     * i_l7_proto:全局使用的l7代号，唯一
     * p_module_name:模块名称
     * ui_mempool_max:缓存池内存大小(单位byte)
     * ; 返回值:成功FR_SUCC, 失败FR_FAIL */
    int (*init)(int i_l7_proto, const char *p_module_name, unsigned int ui_mempool_max);
    int (*destroy)(void); /* 析构函数; 返回值:成功FR_SUCC, 失败FR_FAIL */

    /* 判断是否是当前协议; 返回值:APM_L7_IS_NO,APM_L7_IS_YES,APM_L7_IS_UNKNOWN */
    int (*l7_is)(Conntrack *p_st_conn, Analyze_data_in *p_st_data_in);
    /* 用于L7层数据解码; 返回值: APM_L7_ANALYZE_FAIL,...,APM_L7_ANALYZE_DATA_REQ,APM_L7_ANALYZE_DATA_RESP */
    int (*l7_analyze)(Conntrack *p_st_conn
                    , Analyze_data_in *p_st_input
                    , Frhash_header  *p_st_hash_report   //保存Frreport_data
                    , Frlist_header  *p_st_list_output   //保存Analyz_data_out
                    );
    /* 释放session_private数据;返回值:成功FR_SUCC, 失败FR_FAIL */
    int (*session_destory)(void *p_session_private);

    unsigned long ul_refcnt;        /* 引用次数 */
};
//} L7_module;

/*
* L7_module_plugins
*    依附于L7_module之上的一组Plugin
*       主要用于进一步提取字段信息（如基于HTTP的session username）,采用Lua编写
*/
typedef struct __st_l7_module_plugin {
    int i_proto_depends; /* 依赖的module，采用l7_proto标识 */
    const char *p_plugin_name; /* plugin名 */
    int i_priority;     /* 调用优先级 */
    char *p_lua_src;    /* lua 代码 */
    char *p_lua_fun;    /* 调用lua的函数名 */

    //lua_State *p_lua;
} L7_module_plugin;

#endif
